from flask import Flask, request, Response, jsonify
import pymysql
import xml.etree.ElementTree as ET

import logging

# 配置日志
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

app = Flask(__name__)

# ========== 数据库配置 ==========
DB_CONFIG = {
    "host": "localhost",
    "user": "root",
    "password": "123456",
    "database": "cdm",
    "charset": "utf8mb4"
}


# ================= 打印请求头和请求参数 =================
def log_request(interface_name="接口", params=None):
    logging.info(f"------ {interface_name} 请求头开始 ------")
    for k, v in request.headers.items():
        logging.info(f"{k}: {v}")
    logging.info(f"------ {interface_name} 请求头结束 ------")

    if params:
        logging.info(f"------ {interface_name} 请求参数开始 ------")
        for k, v in params.items():
            logging.info(f"{k}: {v}")
        logging.info(f"------ {interface_name} 请求参数结束 ------")


# ================= 打印请求头函数 =================
def log_request_headers(interface_name="接口"):
    logging.info(f"------ {interface_name} 请求头开始 ------")
    for k, v in request.headers.items():
        logging.info(f"{k}: {v}")
    logging.info(f"------ {interface_name} 请求头结束 ------")


def get_connection():
    """获取数据库连接"""
    return pymysql.connect(**DB_CONFIG)


# =============JSON和XML共用==============
def query_data(table_name, patient_id=None, visit_sn=None, yy_batch_time=None):
    """根据条件查询数据库"""
    connection = get_connection()
    cursor = connection.cursor(pymysql.cursors.DictCursor)

    sql = f"SELECT * FROM {table_name} WHERE 1=1"
    params = []

    if patient_id:
        sql += " AND patient_id = %s"
        params.append(patient_id)

    if visit_sn:
        sql += " AND visit_sn = %s"
        params.append(visit_sn)

    if yy_batch_time:
        sql += " AND yy_batch_time = %s "
        params.append(yy_batch_time)

    cursor.execute(sql, params)
    results = cursor.fetchall()

    cursor.close()
    connection.close()
    return results


def parse_xml_request(xml_data):
    """解析 XML 请求参数"""
    try:
        root = ET.fromstring(xml_data)
        params = {child.tag: child.text.strip() if child.text else "" for child in root}
        return params
    except Exception as e:
        raise ValueError(f"XML 解析失败: {str(e)}")


def build_xml_response(code, msg, data=None):
    """生成 XML 响应"""
    root = ET.Element("root")

    code_node = ET.SubElement(root, "processResultCode")
    code_node.text = str(code)

    msg_node = ET.SubElement(root, "processResult")
    msg_node.text = msg

    contents_node = ET.SubElement(root, "returnContents")

    if data:
        for row in data:
            record_node = ET.SubElement(contents_node, "returnContent")
            for key, value in row.items():
                field_node = ET.SubElement(record_node, key)
                field_node.text = str(value) if value is not None else ""

    return ET.tostring(root, encoding="utf-8", method="xml")


# ================= XML 返回接口 =================
@app.route("/query_xml", methods=["POST"])
def query_xml():
    """仅支持XML请求和返回的接口"""
    try:

        # 1获取XML原始请求体
        xml_raw = request.data.decode("utf-8")
        # 2 解析参数
        params = parse_xml_request(xml_raw)
        # 日志
        log_request("XML接口", params=params)
        table_name = params.get("table_name")
        patient_id = params.get("patient_id")
        visit_sn = params.get("visit_sn")
        yy_batch_time = params.get("yy_batch_time")

        if not table_name:
            error_xml = build_xml_response("EE", "缺少必填参数：table_name")
            return Response(error_xml, mimetype="application/xml")

        # 3 查询数据库
        results = query_data(table_name, patient_id, visit_sn, yy_batch_time)

        # 4 返回结果
        if results:
            xml_data = build_xml_response("cdm数据", "查询成功返回", results)
        else:
            xml_data = build_xml_response("NF", "未查询到数据")

        return Response(xml_data, mimetype="application/xml")

    except ValueError as e:
        error_xml = build_xml_response("EE", str(e))
        return Response(error_xml, mimetype="application/xml")
    except Exception as e:
        error_xml = build_xml_response("EE", f"系统异常: {str(e)}")
        return Response(error_xml, mimetype="application/xml")


# ================= JSON 返回接口 =================
@app.route("/query/json", methods=["POST"])
def query_json():
    try:
        req_data = request.get_json()
        if not req_data:
            return jsonify({"code": "EE", "msg": "请求体必须是 JSON 格式"}), 400
        log_request("HTTP接口", params=req_data)
        table_name = req_data.get("table_name")
        patient_id = req_data.get("patient_id")
        visit_sn = req_data.get("visit_sn")
        yy_batch_time = req_data.get("yy_batch_time")

        if not table_name:
            return jsonify({"code": "EE", "msg": "缺少必填参数 table_name"}), 400

        results = query_data(table_name, patient_id, visit_sn, yy_batch_time)

        if results:
            return jsonify({"code": "AA", "msg": "查询返回", "data": results})
        else:
            return jsonify({"code": "NF", "msg": "未查询到数据", "data": []})

    except Exception as e:
        logging.exception("系统异常")
        return jsonify({"code": "EE", "msg": f"系统异常: {str(e)}"}), 500


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5001, debug=True)
